pyTOF Documentation

The library has three main modules ITA, ITS and ITM. The ITM is still in development, but the two others can be used in order to read your images (.ITA files) or saved spectra (.ITS files).


In [1]:
import matplotlib.pyplot as plt
import numpy as np
from pyTOF import Block,ITA
import os
%matplotlib inline
import matplotlib as mpl
mpl.rc('axes',grid=False)

filename= os.getenv("HOMEPATH")+r"\Dropbox\TOF_SIMS\AuTi_big_40um_24_1.ita"

A = ITA.ITA(filename)

In [2]:
print("The ITA image has {N} scans and a size of {x}x{y} pixels".format(N=A.Nscan,x=A.sx,y=A.sy))


The ITA image has 50 scans and a size of 512x512 pixels

You can see all the channels you recorded and their mass (lower, average and upper mass limit)


In [3]:
A.showMassInt()


0 total  0.0 7500.0 15000.0
1 sum of rest  0.0 7500.0 15000.0
2  C- 11.927536439234666 12.001094203963476 12.075160584208614
3  CH- 12.932266882018785 13.009278773822166 13.08445932408019
4  O- 15.910193242920645 15.94743786240359 16.08062108063093
5  OH- 16.915810666882734 17.000033780017407 17.091773584202834
6  H_2O- 17.915747328515526 18.001566655988906 18.089239057341988
7  F- 18.906130323456473 18.995481172032395 19.091611950375203
8   20.576066921383116 20.697743579090687 20.838167203228547
9  C_2- 23.897526184461178 24.001390963151522 24.104252745245528
10  C_2H- 24.90356811385355 25.00940938126242 25.115485487016755
11  CN- 25.895862219818042 26.00308194723866 26.113469992680777
12  Si- 27.86468707310993 27.97777180439 28.084981783123098
13 S- / O2- S- 31.854601008060346 31.985130557675177 32.11105375878469
14 HS- / O2H-  32.86374961896726 32.99505470846801 33.123198646002194
15 Cl- / OF-  34.848865847411886 34.98361692855124 35.11954274009901
16  ^37Cl- 36.838349622103706 36.97379178802251 37.09158589606625
17   40.84231339596229 41.0103065150852 41.19816826912723
18  CNO- 41.85645474022272 41.99818061997408 42.13684528738758
19  SiO- 44.85976145586887 44.994066012482 45.12882244726282
20   47.83757530139317 47.992062500435196 48.1471950918205
21   48.80222528141344 48.97465293057435 49.15410658395621
22   49.82473713047084 49.991983818960975 50.15291719187662
23   57.789691266853886 57.97976344099958 58.23460459663781
24   59.792655273529675 59.97295336197055 60.16271826676099
25  ^29SiO_2- 60.82639886246742 60.981225644129935 61.13461069390938
26  ^46TiO- 61.77484564369941 61.94937918172839 62.12146854083579
27  ^47TiO- 62.77900349168221 62.94938693838414 63.12276188032475
28 TiO- / SO2- TiO- 63.77168142565455 63.92467262532116 64.12065123372419
29  ^49TiO- 64.78337980033089 64.94991487463099 65.11962540728085
30  ^50TiO- 65.77930195999585 65.94377571218698 66.11811894780676
31   66.7743214741692 66.95174706766201 67.12791068829446
32   68.77675535392711 68.96847107766833 69.2214984857395
33   70.77813795184656 71.00431783508023 71.26741626869537
34   72.77983201933161 73.02744959477151 73.26935628561439
35   74.7369851462289 75.02211508356532 75.2711832554945
36  SiO_3- 75.7889662694538 75.97115059824202 76.16179515263015
37  ^29SiO_3- 76.79019915650211 76.9744836042772 77.1585800633942
38  ^46TiO_2- 77.767429299799 77.95059642801795 78.13841791273815
39  ^47TiO_2- 78.76326526042823 78.95750475338527 79.15195202103487
40 TiO_2- / SO3- TiO_2- 79.753759496096 79.9407378856549 80.13955906165334
41  ^49TiO_2- 80.74510229312973 80.94963394071067 81.14720860317085
42  ^50TiO_2- 81.74495212964807 81.94535360899397 82.14252967583428
43   82.76067952022113 82.95113308867627 83.14831074567707
44   88.74883442676413 89.01372818774243 89.32694211340078
45   94.75001953779932 94.95072827170135 95.164167526136
46  SO_4- 95.72857008366202 95.94406120751029 96.16052562502794
47   96.7389531684518 96.95036064805554 97.15794781513667
48   97.75028003397372 97.95285682496731 98.15149248092784
49   98.72188754772228 98.94273512384906 99.16408792244829
50   100.75076159827557 100.96779591878577 101.18079819707125
51   111.6834314703249 111.90534041526404 112.13617516066564
52   120.70405399743838 120.9450760010655 121.18380197252931
53   122.73144702159848 122.97410405817014 123.21784213913199
54  I- 126.66569241586434 126.9043384322305 127.11359689525912
55  Cs- 132.68314427974877 132.92365590434395 133.1683597023556
56   136.74457413655887 136.97727034411517 137.32264030446416
57   138.6972312426798 138.95255064313466 139.20522114892987
58   152.71349009414897 152.99113731763364 153.33611619919716
59   154.6708850926442 154.98979918363958 155.3382167623408
60   176.55556556019084 176.88985003059832 177.3563303618626
61   194.61496198303286 194.93415381892578 195.41576319554702
62  Au- 196.64826692072594 196.92035987421525 197.3013858112562
63   198.69833077055873 199.04423710383486 199.49679555794143
64   208.66793417032778 208.9910433193903 209.32092349860372
65  AuO- 212.63063651790225 212.9597166356889 213.30454808806937
66   213.6578541999104 213.96614954050915 214.3186914502807
67   215.6397788302731 215.9599305202404 216.28172691114463
68   216.58888825307636 216.96082097344603 217.30047545552785
69   220.63254908916477 220.95845695837608 221.28718535105548
70  CNAu- 222.6312902238245 222.96230530535956 223.31286200514717
71   223.66217413422217 223.98523207022993 224.37370619723887
72  AuO_2- 228.59262159179082 228.92813266041412 229.27155227315347
73   232.64751341694338 232.96360870937403 233.40314421144146
74   239.54195780419528 239.92016040865997 240.43122783238218
75  AuTi- 244.59749031015195 244.94525021386727 245.30442341342524
76   248.61560343499775 248.98214887622012 249.5497050332521
77   256.6278904766244 256.93654267084816 257.46843700515467
78   257.6012961157026 257.91686126080674 258.4021187607039
79  AuTiO- 260.5659939041822 260.9204975671878 261.2802507088057
80   266.54175925369975 266.96540811404776 267.4321434193128
81  AuTiO_2- 276.52029622144295 276.90368369853655 277.284779741753
82   294.47703147326325 294.9229099425824 295.45475144063744

Show the sum of all scans for a specific mass

(e.g. 42u)


In [4]:
plt.imshow(A.getAddedImageByMass(42),cmap='hot');


Show a cross section

(i.e. horizontal axis becomes the spacial axis along the profile and the vertical axis become time as each line a a new scan). This can be useful to check is there is drift or dirt on the surface which should be discarded.


In [5]:
plt.imshow(A.getXsectionByMass(0,255,511,255,0),cmap='hot');


Get the image for a given mass selecting specific scans

The mass is in this example 42u and the scans are given as a list


In [6]:
fig, ax = plt.subplots(1,2,figsize=(14,7))
ax[0].imshow(A.getSumImageByMass(42,range(0,10)),cmap='hot');
ax[0].set_title("10 first scans")
ax[1].imshow(A.getSumImageByMass(42,range(10,A.Nscan)),cmap='hot');
ax[1].set_title("Skipping the 10 first scans");


Get Image by channel Name


In [7]:
Z,ch = A.getAddedImageByName('CN')
print("List of the selected channels")
for z in ch:
    print("\t{name} ({desc}), mass: {lower:.2f} - {upper:.2f}".format(desc=z[b'desc']['utf16'],name=z[b'assign']['utf16'],lower=z[b'lmass']['float'],upper=z[b'umass']['float']))
plt.imshow(Z,cmap='hot');


List of the selected channels
	CN- (), mass: 25.90 - 26.11
	CNO- (), mass: 41.86 - 42.14
	CNAu- (), mass: 222.63 - 223.31

Progressbar

Some process are quite slow depending on how many scans and channels you are summing. If you need all the scans, always use the function getAddedImageByName() and getAddedImageByMass(). Otherwise use getSumImageByName() and getSumImageByMass() which will sum manually all the selected scans.

As this progress might be slow you can display a progressbar of the current status by adding the option prog=True to your functions. Note that this requires to have the library tqdm installed [ https://pypi.python.org/pypi/tqdm ]


In [8]:
from IPython.display import HTML

fig, ax = plt.subplots(1,2,figsize=(14,7))
# Very Fast
Z,ch = A.getAddedImageByName('C')
v="<h3>List of the selected channels</h3><ul>"
for z in ch:
    v+="<li>{name} ({desc}) {lower:.2f} - {upper:.2f}</li>".format(desc=z[b'desc']['utf16'],name=z[b'assign']['utf16'],lower=z[b'lmass']['float'],upper=z[b'umass']['float'])
v+="</ul>"
ax[0].imshow(Z,cmap='hot');
HTML(v)

# Slow. Add a progressbar
Z,ch = A.getSumImageByName('C',prog=True)
ax[1].imshow(Z,cmap='hot');


                                                                     

Image collection

A ToF-SIMS file is actually a collection of many images coming from different channels. Instead of loading each channel manualy, a new class was developed in order to speed up the coding.


In [9]:
B = ITA.ITA_collection(filename,['Ti','Au','C'])

print("Channel selected")
print(B.msg)


Channel selected
Ti
	TiO- (TiO- / SO2-), mass: 63.77 - 64.12
	TiO_2- (TiO_2- / SO3-), mass: 79.75 - 80.14
Au
	Au- (), mass: 196.65 - 197.30
	AuO- (), mass: 212.63 - 213.30
	AuO_2- (), mass: 228.59 - 229.27
	AuTi- (), mass: 244.60 - 245.30
	AuTiO- (), mass: 260.57 - 261.28
	AuTiO_2- (), mass: 276.52 - 277.28
C
	C- (), mass: 11.93 - 12.08
	CH- (), mass: 12.93 - 13.08
	C_2- (), mass: 23.90 - 24.10
	C_2H- (), mass: 24.90 - 25.12
	CN- (), mass: 25.90 - 26.11
	 (Cl- / OF-), mass: 34.85 - 35.12
	CNO- (), mass: 41.86 - 42.14
	Cs- (), mass: 132.68 - 133.17
	CNAu- (), mass: 222.63 - 223.31

The channel selected is listed in the B.msg string. In case you want only the Au,AuO and AuO_2 channels, you can use regexp (https://docs.python.org/2/library/re.html) to target the channel more acurately:


In [10]:
B = ITA.ITA_collection(filename,['Ti','Au[O_0-9]*-$','C'])

print("Channel selected")
print(B.msg)


Channel selected
Ti
	TiO- (TiO- / SO2-), mass: 63.77 - 64.12
	TiO_2- (TiO_2- / SO3-), mass: 79.75 - 80.14
Au[O_0-9]*-$
	Au- (), mass: 196.65 - 197.30
	AuO- (), mass: 212.63 - 213.30
	AuO_2- (), mass: 228.59 - 229.27
C
	C- (), mass: 11.93 - 12.08
	CH- (), mass: 12.93 - 13.08
	C_2- (), mass: 23.90 - 24.10
	C_2H- (), mass: 24.90 - 25.12
	CN- (), mass: 25.90 - 26.11
	 (Cl- / OF-), mass: 34.85 - 35.12
	CNO- (), mass: 41.86 - 42.14
	Cs- (), mass: 132.68 - 133.17
	CNAu- (), mass: 222.63 - 223.31

This will lead to a channel name with a weird name (regexp string). You can use your own name by using a dictionnary as follow:


In [11]:
B = ITA.ITA_collection(filename,{'Ti':'Ti','Au':'Au[O_0-9]*-$','C':'C'},name='Example')

print("Channel selected")
print(B.msg)


Channel selected
Ti
	TiO- (TiO- / SO2-), mass: 63.77 - 64.12
	TiO_2- (TiO_2- / SO3-), mass: 79.75 - 80.14
C
	C- (), mass: 11.93 - 12.08
	CH- (), mass: 12.93 - 13.08
	C_2- (), mass: 23.90 - 24.10
	C_2H- (), mass: 24.90 - 25.12
	CN- (), mass: 25.90 - 26.11
	 (Cl- / OF-), mass: 34.85 - 35.12
	CNO- (), mass: 41.86 - 42.14
	Cs- (), mass: 132.68 - 133.17
	CNAu- (), mass: 222.63 - 223.31
Au
	Au- (), mass: 196.65 - 197.30
	AuO- (), mass: 212.63 - 213.30
	AuO_2- (), mass: 228.59 - 229.27

Plotting all the channel of interest (here Ti, Au carbons) has never been so easy:


In [12]:
B.show()


The title will contains the name of the collection (given by the name argument of the _ITA.ITAcollection function. If not provided, the filename will be used) and the channel name.

PCA

The ITA_container is very usefull to perform PCA on the sample. It's also very very easy to use it:


In [13]:
B.showPCA()
print(B.loadings())


         Au         C        Ti
0 -0.689648  0.154154  0.707546
1  0.223273  0.974742  0.005258
2  0.688864 -0.161602  0.706648

The PCA object is the variable P (so B.P is this example). You can call various PCA functions (still in development for the moment).


In [14]:
B.P.screeplot()



In [15]:
B.P.pca_scatter()



In [16]:
# Shows the correlation matrix
B.P.corrShow()



In [17]:
# Shows the hinton plot of the correlation matrix
B.P.hinton()



In [18]:
B.P.pca_summary()


Out[18]:
sdev varprop cumprop
Standard deviation Proportion of Variance Cumulative Proportion
PC1 1.379819 0.634634 0.634634
PC2 1.001150 0.334100 0.968734
PC3 0.306266 0.031266 1.000000

In [19]:
B.P.showStand()


Out[19]:
Au C Ti
Mean -5.204170e-18 6.830474e-18 3.122502e-17
Std 1.000000e+00 1.000000e+00 1.000000e+00

Hack raw data

This library is far from complete and you might want to hack the raw data to find useful information out of your data like the date, comments, beam energy, etc.

The raw data are represented by hierarchic blocks. The root block is the object A.root (if A is the ITA.ITA object). Each children can be listed as follow:


In [20]:
A.root.showList()


List of 18 elements. Type: 6403
b'versionheader' (0) [1] <265> @567
b'Analysis' (0) [1] <2650> @940
b'TotalArea' (0) [1] <2650> @3623
b'MassScale' (0) [1] <2650> @6307
b'MassIntervalList' (0) [1] <2650> @8991
b'Meta' (0) [1] <2650> @11682
b'propstart' (0) [1] <2650> @14361
b'propend' (0) [1] <2650> @17045
b'Options' (0) [1] <2650> @19727
b'Measurement Options' (0) [1] <2650> @22409
b'Peaklists' (0) [1] <2650> @25103
b'LateralShiftCorrection' (0) [1] <2650> @27787
b'SampleHolderInfo' (0) [1] <2650> @31065
b'StorageInfo' (0) [1] <530> @33756
b'filterdata' (0) [1] <795> @34443
b'PropertyTrends' (0) [1] <1590> @59508303
b'Presentation' (0) [1] <530> @59882590
b'finder.info.simplejson.6' (0) <85502> @59883157, value = b'5b00220056004500...' (hex) = ["VERSION.2a", {"SIM... (UTF-16)

You can reach a specific children throught it's path as a file in a folder with:

A.root.goto("filterdata/TofCorrection/ImageStack")

Large binary data, such as images are compressed with the zlib library. The following example show you how to plot the firt image saved (the total counts).


In [21]:
import zlib
import struct
import matplotlib as mpl

RAW=A.root.goto("filterdata/TofCorrection/ImageStack/Reduced Data/ImageStackScansAdded/Image/ImageArray.Long").value
D = zlib.decompress(RAW)
V = np.array(struct.unpack('<'+str(A.sx*A.sy)+'I',D),dtype=np.float).reshape((A.sy,A.sx))

mpl.rc('axes',grid=False)
plt.imshow(V,cmap='hot');